package com.kaifamiao.month03.day0322;

/**
 * 设计一个方法返回该数二进制表示形式
 * 短除法
 */
public class GetBinary {

    public static void main(String[] args) {
        int[] arr = getBinary(-10);
        for (int a : arr) {
            System.out.print(a);
        }
        System.out.println();
        System.out.println(Integer.toBinaryString(-10));
        System.out.println(toDec(arr));
    }

    /**
     * 将十进制数字转换成二进制
     * @param num 需要转换的十进制数字
     * @return 转换成二进制的字符串
     */
    public static int[] getBinary(int num) {
        int[] arr = new int[32];
        int that = Math.abs(num);
        int count = 31;
        while (that != 0) {
            arr[count--] = that % 2;
            that >>>= 1;
        }
        if (num < 0) { // 如果是负数 先转为反码，再取补码
            arr = getBinary(toDec(getInvert(arr)) + 1);
            arr[0] = 1; // 符号位
        }
        return arr;
    }

    /**
     * 将二进制字符串转换成十进制数字
     * @param arr 需要转换的二进制数组
     * @return 返回转换成十进制的数字
     */
    public static int toDec(int[] arr) {
        int result = 0;
        if (arr[0] != 1) {
            for (int i = 1; i < arr.length; i++) {
                if (arr[i] != 0) {
                    result += Math.pow(2, arr.length - 1 - i);
                }
            }
        } else { // 符号位为 0 先取反码 然后转为原码计算
            arr[0] = 0;
            result = toDec(getInvert(getBinary(toDec(arr) - 1))) * (-1);
        }
        return result;
    }

    /**
     * 取反码
     * @param arr 需要取反码的二进制数组
     * @return 反码之后的数组
     */
    public static int[] getInvert(int[] arr) {
        for(int i = 1; i < arr.length; i ++){
            arr[i] = arr[i] == 0 ? 1 : 0;
        }
        return arr;
    }
}
